package com.icinfo.cloud.provider.handler;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.icinfo.cloud.provider.common.exception.BusinessException;
import com.icinfo.cloud.provider.common.utils.Md5Util;
import com.icinfo.cloud.provider.logs.model.AppAuthorizationBusiRequestLog;
import com.icinfo.cloud.provider.logs.service.IAppAuthorizationBusiRequestLogService;
import com.icinfo.cloud.provider.punish.config.service.IConfigAppAuthorizationRecordService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;

/**
 * 描述：app接入授权处理
 *
 * @Author zhengqiang
 * @Date 2022/8/16 17:49
 **/
@Component
@Aspect
@Slf4j
public class AppAuthorizationHandler {

    @Resource
    private IConfigAppAuthorizationRecordService configAppAuthorizationRecordService;
    @Resource
    private IAppAuthorizationBusiRequestLogService appAuthorizationBusiRequestLogService;

    @Pointcut("execution(*  com.icinfo.cloud.provider.punish.csource.manage.controller.CaseSourceApiController.*(..))  " +
            "|| execution(* com.icinfo.cloud.provider.peripheralinterface.healthcare.controller.HealthCareController.*(..))" +
            "|| execution(* com.icinfo.cloud.provider.punish.api.controller.PunishCaseMainInfoController.*(..))")
    public void controllerPointcut(){}

//    @Before("controllerPointcut()")
//    public void before(JoinPoint joinPoint) {
//        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//        HttpServletRequest request = requestAttributes.getRequest();
//
//        log.info("Before：url={}",request.getRequestURL());
//        //获取appId,请求时间戳和安全码
//        String appId = "";
//        String requestTime = "";
//        String security = "";
//        String paramStr = "";
//        for(Object temp : joinPoint.getArgs()){
//            if (!ObjectUtils.isEmpty(temp)) {
//                JSONObject jsonObject = (JSONObject) JSONObject.toJSON(temp);
//                paramStr = JSONObject.toJSONString(jsonObject);
//                log.info("param= {} ", jsonObject);
//                appId = jsonObject.getString("caseSourceAppId");
//                requestTime = jsonObject.getString("requestTime");
//                security = jsonObject.getString("security");
//            }
//        }
//
//        if (ObjectUtils.isEmpty(appId) || ObjectUtils.isEmpty(requestTime)) {
//            throw new BusinessException("应用id及请求时间戳不能为空");
//        }
//
//        //查询应授权记录
//        String appKey = configAppAuthorizationRecordService.getAppKeyByAppId(appId);
//        if (ObjectUtils.isEmpty(appKey)) {
//            throw new BusinessException("应用未授权-appId:" + appId);
//        }
//
//        //验证安全码是否正确
//        //加密方法MD5(appId + appKey + requestTime)
//        String localSecurity = "";
//        try {
//            localSecurity = Md5Util.md5(appId + appKey + requestTime);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//
//        if (!localSecurity.equals(security)) {
//            log.info("校验失败：应用安全码有误;  paramStr:" + paramStr);
//            throw new BusinessException("应用安全码有误");
//        }
//
//    }




    @Before("controllerPointcut()")
    public void before(JoinPoint joinPoint) throws Exception {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();

        log.info("Before：url={}",request.getRequestURL());
        //获取appId,请求时间戳和安全码
        String appId = "";
        String requestTime = "";
        String security = "";
        String paramStr = "";
        boolean isSaveLog = false;
        if (ObjectUtil.isNotEmpty(request.getRequestURL())
                && request.getRequestURL().toString().contains("/punish/csource/manage/api")) {
            //案源接口保存日志
            isSaveLog = true;
        }
        for(Object temp : joinPoint.getArgs()){
            if (!ObjectUtils.isEmpty(temp)) {
                if (isSaveLog) {
                    JSONObject jsonObject = (JSONObject) JSONObject.toJSON(temp);
                    paramStr = JSONObject.toJSONString(jsonObject);
                }
                appId =getValueByKey(temp,"caseSourceAppId");
                requestTime = getValueByKey(temp,"requestTime");
                security = getValueByKey(temp,"security");
            }
        }

        //保存请求日志
        if (isSaveLog) {
            AppAuthorizationBusiRequestLog requestLog = new AppAuthorizationBusiRequestLog();
            if (ObjectUtil.isNotEmpty(request.getRequestURL())) {
                requestLog.setRequestUrl(request.getRequestURL().toString());
            }
            requestLog.setAppId(appId);
            requestLog.setRequestContent(paramStr);
            appAuthorizationBusiRequestLogService.saveAppAuthorizationBusiRequestLog(requestLog);
        }

        if (ObjectUtils.isEmpty(appId) || ObjectUtils.isEmpty(requestTime)) {
            throw new BusinessException("应用id及请求时间戳不能为空");
        }

        //查询应授权记录
        String appKey = configAppAuthorizationRecordService.getAppKeyByAppId(appId);
        if (ObjectUtils.isEmpty(appKey)) {
            throw new BusinessException("应用未授权-appId:" + appId);
        }

        //验证安全码是否正确
        //加密方法MD5(appId + appKey + requestTime)
        String localSecurity = "";
        try {
            localSecurity = Md5Util.md5(appId + appKey + requestTime);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (!localSecurity.equals(security)) {
            log.info("校验失败：应用签名有误;  paramStr:" + paramStr);
            throw new BusinessException("应用签名有误");
        }

    }

    /**
     * 获取对象的某个键的值
     *
     * @param obj 对象
     * @param key 键
     * @return {@link String }
     * @author shishengyao
     * @date 2023/03/13
     */
    public static String getValueByKey(Object obj, String key) throws IllegalAccessException {
        if (null==key || key==""){
            return "";
        }
        final Field[] declaredFields = obj.getClass().getDeclaredFields();
        /* 得到类中的所有属性集合 */
        for (Field declaredField : declaredFields) {
            declaredField.setAccessible(true);
            if (key.equals(declaredField.getName())){
                return declaredField.get(obj).toString();
            }
        }
        // 没有查到时返回空字符串
        return "";
    }

}
